<template>
  <draggable
    v-bind="{ ...$attrs, ...onBind() }"
    :list="list"
    class="drag-box"
    ghost-class="ghost"
    chosen-class="chosen"
    drag-class="dran"
    :animation="200"
    itemKey="id"
    :force-fallback="true"
    :group="{ name: 'components', pull: true, put: true }"
    :fallback-class="true"
    :fallback-on-body="true"
  >
    <template #item="{ element }">
      <a-col v-bind="element.grid" class="item move" @click.stop>
        <slot name="item" :element="element">
          <template v-if="$props.draggable == true">
            <a-dropdown
              trigger="contextMenu"
              alignPoint
              :style="{ display: 'block' }"
              @contextmenu.stop
            >
              <div
                :class="{
                  'list-group-item': true,
                  'list-group-item-pitch': element.id == formStore.moduleKey,
                }"
                :style="element.style"
                @click="onSelect(element)"
              >
                <itemVue :element="element"></itemVue>
              </div>
              <template #content>
                <a-doption @click="onCopy(element)">拷贝</a-doption>
                <a-doption @click="onRemove(element.id)">删除</a-doption>
              </template>
            </a-dropdown>
          </template>
          <template v-else>
            <itemVue :element="element"></itemVue>
          </template>
        </slot>
      </a-col>
    </template>
  </draggable>
</template>

<script setup lang="tsx">
import { computed, ref, inject, watch, h } from "vue";
import { useVModel } from "@vueuse/core";
import draggable from "vuedraggable";
import itemVue from "@/components/draggable/item.vue";
import { getById } from "@/utils/index.ts";
import { Message } from "@arco-design/web-vue";
import { useFormStore } from "@/store/form.ts";
import { cloneDeep } from "lodash";
interface Props {
  list: any[];
  draggable?: boolean;
}
const emit = defineEmits(["update:list"]);
const props = withDefaults(defineProps<Props>(), {
  list: () => [],
  draggable: false,
});
const formStore = useFormStore();
const list = useVModel(props, "list", emit);
const onBind = () => {
  let draggable;
  if (props.draggable == true) {
    draggable = undefined;
  } else {
    draggable = true;
  }
  return {
    draggable,
  };
};
// 选中
const onSelect = (item) => {
  Message.info({
    content: () => {
      return (
        <>
          选中{item.label}:<span style="color: blue">{item.name} </span> , ID:
          <span style="text-decoration: underline;color:blue">{item.id}</span>
        </>
      );
    },
    showIcon: true,
  });
  formStore.moduleKey = [item.id];
};
const onRemove = (id) => {
  list.value = list.value.filter((item) => item.id !== id);
};
const onCopy = (item) => {
  // 递归
  function copy(item) {
    let obj: any = {};
    obj = { ...cloneDeep(item), id: getById() };
    if (item.children && item.children.length > 0) {
      obj.children = item.children.map((item) => copy(item));
    }
    return obj;
  }
  list.value.push(copy(item));
};
defineOptions({
  name: "Draggable",
});
defineExpose({
  onSelect,
  onRemove,
  onCopy,
  onBind,
  list,
});
</script>

<style lang="scss" scoped>
.drag-box {
  display: flex;
  flex-wrap: wrap;
  .item {
    padding: 2px;
  }
}
.ghost {
  width: 100%;
  pointer-events: none;
  opacity: 0.5;
  background: #c8ebfb;
  border: 1px dashed #3196fa;
  box-sizing: border-box;
}
.dran {
  opacity: 0.5;
}
.list-group-item {
  display: inline-block;
  border: 1px solid #ffffff00;
  &:hover {
    cursor: move;
    border: 1px dashed blue;
  }
}
.list-group-item-pitch {
  border: 1px solid blue;
  &:hover {
    cursor: move;
    border: 1px solid blue;
  }
}
</style>
